﻿// See https://aka.ms/new-console-template for more information

Animal animal1 = new Animal();

Cat cat1 = new Cat();

Animal animal2 = new Cat();

//Cat cat2 = (Cat)new Animal();

List<Animal> animals = new List<Animal>();

//c#语法中 只能使用父类来声明子类
//List<Animal> animals2=new List<Cat>();
List<Animal> animals2 = new List<Cat>().Select(x => (Animal)x).ToList();

//协变，类型参数用out修饰 类型参数只能作为返回值，不能作为入参数
//效果：可以让左边使用父类，右边使用子类
IEnumerable<Animal> animalList = new List<Animal>(); //一堆动物是一堆动物
IEnumerable<Animal> animalList2 = new List<Cat>();//一堆猫是一堆动物
ICustomerListOut<Animal> cutomerListOut1 = new CustomerListOut<Animal>();
ICustomerListOut<Animal> cutomerListOut2 = new CustomerListOut<Cat>();

//逆变 类型参数用in修饰， 类型参数只能做参数，不能做返回值
//效果：可以让左边使用子类，右边使用父类
ICustomerListIn<Cat> cutomerListIn1 = new CustomerListIn<Animal>();
ICustomerListIn<Cat> cutomerListIn2 = new CustomerListIn<Cat>();

//逆变协变：一个规避风险的约束
//效果：让泛型更和谐
//逆变协变的存在，就是为了让常规场景添加一个规避风险的约束
IMyList<Cat, Animal> myList1 = new MyList<Cat, Animal>();
IMyList<Cat, Animal> myList2 = new MyList<Cat, Cat>();//协变
IMyList<Cat, Animal> myList3 = new MyList<Animal, Animal>();//逆变
IMyList<Cat, Animal> myList4 = new MyList<Animal, Cat>();//协变+逆变

//协变逆变只能出现在
//泛型接口
//泛型委托

Console.WriteLine("Hello, World!");

internal class Animal
{
    public int Id { get; set; }
}

internal class Cat : Animal
{
    public string Name { get; set; }
}

internal interface ICustomerListOut<out T>
{
    T Get();
}

internal class CustomerListOut<T> : ICustomerListOut<T>
{
    public T Get()
    {
        return default;
    }
}

internal interface ICustomerListIn<in T>
{
    void Get(T par);
}

internal class CustomerListIn<T> : ICustomerListIn<T>
{
    public void Get(T par)
    {
    }
}

internal interface IMyList<in T1, out T2>
{
}

internal class MyList<T1, T2> : IMyList<T1, T2>
{
}